
package com.rt.schedulenew.service.impl;

import com.rt.schedulebase.dto.*;
import com.rt.schedulebase.entity.DictExamQueue;
import com.rt.schedulebase.entity.DictHospital;

import java.util.*;
import java.text.ParseException;

import com.rt.schedulebase.mapper.ChartsMapper;
import com.rt.schedulebase.mapper.DictScheduleApmMapper;

import java.text.NumberFormat;

import com.rt.schedulebase.dto.BreakPromiseCountDto;
import com.rt.schedulebase.entity.DictDept;
import com.rt.schedulebase.entity.ScheduleTerminal;

import com.rt.schedulenew.api.IDictDeptService;
import com.rt.schedulenew.api.IDictPatientSourceService;
import com.rt.schedulenew.utils.util.DateUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import com.alibaba.fastjson.JSON;
import com.rt.schedulenew.utils.base.BigDecimalUtil;
import com.rt.schedulebase.entity.DictPatientSource;

import com.rt.schedulenew.utils.base.ConstantsUtil;
import com.rt.schedulenew.utils.base.CommonUtil;

import java.util.stream.Collectors;

import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import com.rt.schedulenew.api.IChartsService;

@Service
public class ChartsServiceImpl implements IChartsService {
    @Autowired
    private ChartsMapper chartsMapper;
    @Autowired
    private IChartsService iChartsService;
    @Autowired
    private DictHospitalServiceImpl dictHospitalService;
    @Autowired
    private IDictDeptService dictDeptService;
    @Autowired
    private DictExamQueueServiceImpl dictExamQueueService;
    @Autowired
    private IDictPatientSourceService dictPatientSourceService;
    @Autowired
    private DictScheduleApmMapper dictScheduleApmMapper;

    /***
     * 预约量统计-申请院区
     * @param dto
     * @return
     */
    @Override
    public Map<String, Object> getReqHospitalCount(ChartsDto dto) {
        Map<String, Object> map = new HashMap<String, Object>();
        String countType = dto.getCountType();
        dto.setExamClasses(CommonUtil.split2List(dto.getExamClass()));
        if (ConstantsUtil.CountType.YEAR.name().equals(countType)) {
            // 获取医院 和患者来源 分组的数量
            List<ChartsDto> chartsCounts = chartsMapper.getReqHospitalCount4Year(dto);
            map = getHospitalCountData(chartsCounts);
        } else if (ConstantsUtil.CountType.MONTH.name().equals(countType)) {
            List<ChartsDto> chartsCounts = chartsMapper.getReqHospitalCount4Month(dto);
            map = getHospitalCountData(chartsCounts);
        } else if (ConstantsUtil.CountType.DATE.name().equals(countType)) {
            List<ChartsDto> chartsCounts = chartsMapper.getReqHospitalCount4Date(dto);
            map = getHospitalCountData(chartsCounts);
        }
        return map;
    }

    /***
     * 构建和计算百分比占比
     * @param chartsCounts
     * @return
     */
    private Map<String, Object> getHospitalCountData(List<ChartsDto> chartsCounts) {
        Map<String, Integer> map = new HashMap<>();
        // 获取院区列表
        List<DictHospitalDto> hospitals = dictHospitalService.getHospitalList(new DictHospitalDto());
        // 患者来源
        List<DictPatientSource> sources = dictPatientSourceService.getListAll();
        int total = 0;
        for (ChartsDto chartsDto : chartsCounts) {
            String key = chartsDto.getReqHospitalCode() + "_" + chartsDto.getPatientSource();
            map.put(key, chartsDto.getCount());
            total += ((chartsDto.getCount() != null) ? chartsDto.getCount() : 0);
        }
        Map<String, Object> result = new TreeMap<>();
        List<Map<String, Object>> list = new ArrayList<>();
        // 院区
        for (DictHospital hospital : hospitals) {
            Map<String, Object> m = new TreeMap<>();
            m.put("hospitalName", hospital.getHospitalName());
            int sum = 0;
            for (DictPatientSource source : sources) {
                String key = hospital.getHospitalName() + "_" + source.getPatientSourceName();
                Integer value = map.get(key);
                sum += ((value != null) ? value : 0);
                m.put("source" + source.getPatientSourceCode(), (value != null) ? value : 0);
            }
            m.put("sum", sum);
            if (sum > 0) {
                m.put("ratio", BigDecimalUtil.divide(sum, total, 2));
            }
            list.add(m);
        }
        String columnStr = "[{\"prop\":\"hospitalName\",\"label\":\"院区名称\"},";
        columnStr = getColumnString(columnStr, sources);
        result.put("column", JSON.parse(columnStr));
        result.put("data", list);
        return result;
    }

    @Override
    public Map<String, Object> getTerminalTypeCount(ChartsDto dto) {
        Map<String, Object> map = new HashMap<String, Object>();
        String countType = dto.getCountType();
        dto.setExamClasses(CommonUtil.split2List(dto.getExamClass()));
        if (ConstantsUtil.CountType.YEAR.name().equals(countType)) {
            List<ChartsDto> chartsCounts = chartsMapper.getTerminalTypeCount4Year(dto);
            map = getTerminalTypeCountData(chartsCounts);
        } else if (ConstantsUtil.CountType.MONTH.name().equals(countType)) {
            List<ChartsDto> chartsCounts = chartsMapper.getTerminalTypeCount4Month(dto);
            map = getTerminalTypeCountData(chartsCounts);
        } else if (ConstantsUtil.CountType.DATE.name().equals(countType)) {
            List<ChartsDto> chartsCounts = chartsMapper.getTerminalTypeCount4Date(dto);
            map = getTerminalTypeCountData(chartsCounts);
        }
        return map;
    }

    @Override
    public Map<String, Object> getPerformDeptTerminalCount(ChartsDto dto) {
        dto.setExamClasses(CommonUtil.split2List(dto.getExamClass()));
        List<ChartsDto> chartsCounts = chartsMapper.getPerformDeptTerminalCount(dto);
        List<String> column = new ArrayList<String>();
        column.add("预约渠道");
        column.add("操作人科室");
        Map<String, Integer> map_chartsCounts = new HashMap<String, Integer>();
        Map<String, List<String>> deptMap = new HashMap<String, List<String>>();
        int total = 0;
        List<String> terminals = new ArrayList<String>();
        List<String> performDeptNames = new ArrayList<String>();
        for (ChartsDto chartsDto : chartsCounts) {
            if (!column.contains(chartsDto.getPerformDeptName())) {
                column.add(chartsDto.getPerformDeptName());
                performDeptNames.add(chartsDto.getPerformDeptName());
            }
            if (!terminals.contains(chartsDto.getTerminalType())) {
                terminals.add(chartsDto.getTerminalType());
            }
            List<String> depts = deptMap.get(chartsDto.getTerminalType());
            if (depts == null) {
                depts = new ArrayList<>();
            }
            if (!depts.contains(chartsDto.getDeptName())) {
                depts.add(chartsDto.getDeptName());
                deptMap.put(chartsDto.getTerminalType(), depts);
            }
            String key = "";
            if ("C".equals(chartsDto.getTerminalType()) || "D".equals(chartsDto.getTerminalType()) || StringUtils.isBlank(chartsDto.getDeptName())) {
                key = chartsDto.getTerminalType() + "_" + chartsDto.getPerformDeptName();
                Set<String> mapKeys = map_chartsCounts.keySet();
                map_chartsCounts.put(key, chartsDto.getCount() + (mapKeys.contains(key) ? map_chartsCounts.get(key) : 0));
            } else {
                key = chartsDto.getTerminalType() + "_" + chartsDto.getPerformDeptName() + "_" + chartsDto.getDeptName();
                map_chartsCounts.put(key, chartsDto.getCount());
            }
            total += ((chartsDto.getCount() != null) ? chartsDto.getCount() : 0);
        }
        Map<String, Object> map = new HashMap<>();
        List<Map<String, Object>> list = new ArrayList<>();
        for (String terminalType : terminals) {
            if ("C".equals(terminalType) || "D".equals(terminalType)) {
                Map<String, Object> m = new TreeMap<>();
                int sum = 0;
                m.put("terminalType", CommonUtil.convertTerminalType(terminalType));
                for (String performDeptName : performDeptNames) {
                    Integer value = map_chartsCounts.get(terminalType + "_" + performDeptName);
                    sum += ((value != null) ? value : 0);
                    m.put(performDeptName, (value != null) ? value : 0);
                }
                m.put("dept", null);
                m.put("sum", sum);
                if (sum > 0) {
                    m.put("ratio", BigDecimalUtil.divide(sum, total, 2));
                }
                list.add(m);
            } else {
                List<String> depts2 = deptMap.get(terminalType);
                if (depts2 != null && depts2.size() > 0) {
                    for (String dept : depts2) {
                        Map<String, Object> i = new TreeMap<String, Object>();
                        int sum2 = 0;
                        if ("O".equals(terminalType)) {
                            i.put("terminalType", "其他");
                        } else {
                            i.put("terminalType", CommonUtil.convertTerminalType(terminalType));
                        }
                        for (String performDeptName2 : performDeptNames) {
                            String key2 = terminalType + "_" + performDeptName2 + "_" + dept;
                            Integer value2 = map_chartsCounts.get(key2);
                            sum2 += ((value2 != null) ? value2 : 0);
                            i.put(performDeptName2, (value2 != null) ? value2 : 0);
                        }
                        i.put("dept", dept);
                        i.put("sum", sum2);
                        if (sum2 > 0) {
                            i.put("ratio", BigDecimalUtil.divide((double) sum2, (double) total, 2));
                        }
                        list.add(i);
                    }
                } else {
                    Map<String, Object> j = new TreeMap<String, Object>();
                    int sum3 = 0;
                    if ("O".equals(terminalType)) {
                        j.put("terminalType", "其他");
                    } else {
                        j.put("terminalType", CommonUtil.convertTerminalType(terminalType));
                    }
                    for (String performDeptName3 : performDeptNames) {
                        Integer value3 = map_chartsCounts.get(terminalType + "_" + performDeptName3);
                        sum3 += ((value3 != null) ? value3 : 0);
                        j.put(performDeptName3, (value3 != null) ? value3 : 0);
                    }
                    j.put("dept", null);
                    j.put("sum", sum3);
                    if (sum3 > 0) {
                        j.put("ratio", BigDecimalUtil.divide((double) sum3, (double) total, 2));
                    }
                    list.add(j);
                }
            }
        }
        column.add("合计");
        column.add("占比");
        map.put("column", column);
        map.put("data", list);
        return map;
    }

    private Map<String, Object> getTerminalTypeCountData(List<ChartsDto> chartsCounts) {
        List<DictPatientSource> sources = dictPatientSourceService.getListAll();
        Map<String, Integer> map_chartsCounts = new HashMap<>();
        Map<String, List<String>> deptMap = new HashMap<>();
        int total = 0;
        List<String> terminals = new ArrayList<String>();
        for (ChartsDto chartsDto : chartsCounts) {
            if (!terminals.contains(chartsDto.getTerminalType())) {
                terminals.add(chartsDto.getTerminalType());
            }
            if (StringUtils.isNotBlank(chartsDto.getTerminalType())) {
                List<String> depts = deptMap.get(chartsDto.getTerminalType());
                if (depts == null) {
                    depts = new ArrayList<>();
                }
                if (!depts.contains(chartsDto.getDeptName())) {
                    depts.add(chartsDto.getDeptName());
                    deptMap.put(chartsDto.getTerminalType(), depts);
                }
                String key = "";
                if ("C".equals(chartsDto.getTerminalType()) || "D".equals(chartsDto.getTerminalType()) || StringUtils.isBlank((CharSequence) chartsDto.getDeptName())) {
                    key = chartsDto.getTerminalType() + "_" + chartsDto.getPatientSource();
                    Set<String> mapKeys = map_chartsCounts.keySet();
                    map_chartsCounts.put(key, chartsDto.getCount() + (mapKeys.contains(key) ? map_chartsCounts.get(key) : 0));
                } else {
                    key = chartsDto.getTerminalType() + "_" + chartsDto.getPatientSource() + "_" + chartsDto.getDeptName();
                    map_chartsCounts.put(key, chartsDto.getCount());
                }
                total += ((chartsDto.getCount() != null) ? chartsDto.getCount() : 0);
            }
        }
        Map<String, Object> map = new HashMap<String, Object>();
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        for (String terminalType : terminals) {
            if ("C".equals(terminalType) || "D".equals(terminalType)) {
                int sum = 0;
                Map<String, Object> m = new TreeMap<String, Object>();
                m.put("terminalType", CommonUtil.convertTerminalType(terminalType));
                for (DictPatientSource source : sources) {
                    Integer value = map_chartsCounts.get(terminalType + "_" + source.getPatientSourceName());
                    sum += ((value != null) ? value : 0);
                    m.put("source" + source.getPatientSourceCode(), (value != null) ? value : 0);
                }
                m.put("dept", null);
                m.put("sum", sum);
                if (sum > 0) {
                    m.put("ratio", BigDecimalUtil.divide(sum, total, 2));
                }
                list.add(m);
            } else {
                List<String> depts2 = deptMap.get(terminalType);
                if (depts2 != null && depts2.size() > 0) {
                    for (String dept : depts2) {
                        int sum2 = 0;
                        Map<String, Object> i = new TreeMap<String, Object>();
                        if ("O".equals(terminalType)) {
                            i.put("terminalType", "其他");
                        } else {
                            i.put("terminalType", CommonUtil.convertTerminalType(terminalType));
                        }
                        for (DictPatientSource source2 : sources) {
                            String key2 = terminalType + "_" + source2.getPatientSourceName() + "_" + dept;
                            Integer value2 = map_chartsCounts.get(key2);
                            sum2 += ((value2 != null) ? value2 : 0);
                            i.put("source" + source2.getPatientSourceCode(), (value2 != null) ? value2 : 0);
                        }
                        i.put("dept", dept);
                        i.put("sum", sum2);
                        if (sum2 > 0) {
                            i.put("ratio", BigDecimalUtil.divide(sum2, total, 2));
                        }
                        list.add(i);
                    }
                } else {
                    int sum3 = 0;
                    Map<String, Object> j = new TreeMap<String, Object>();
                    if ("O".equals(terminalType)) {
                        j.put("terminalType", "其他");
                    } else {
                        j.put("terminalType", CommonUtil.convertTerminalType(terminalType));
                    }
                    for (DictPatientSource source3 : sources) {
                        Integer value3 = map_chartsCounts.get(terminalType + "_" + source3.getPatientSourceName());
                        sum3 += ((value3 != null) ? value3 : 0);
                        j.put("source" + source3.getPatientSourceCode(), (value3 != null) ? value3 : 0);
                    }
                    j.put("dept", null);
                    j.put("sum", sum3);
                    if (sum3 > 0) {
                        j.put("ratio", BigDecimalUtil.divide((double) sum3, (double) total, 2));
                    }
                    list.add(j);
                }
            }
        }
        String columnStr = "[{\"prop\":\"terminalType\",\"label\":\"预约方式\"},{\"prop\":\"dept\",\"label\":\"操作人科室\"},";
        columnStr = getColumnString(columnStr, sources);
        map.put("column", JSON.parse(columnStr));
        map.put("data", list);
        return map;
    }

    @Override
    public Map<String, Object> getScheduleTerminalCount(ChartsDto dto) {
        String countType = dto.getCountType();
        Map<String, Object> map = null;
        dto.setExamClasses(CommonUtil.split2List(dto.getExamClass()));
        if (ConstantsUtil.CountType.YEAR.name().equals(countType)) {
            List<ChartsDto> chartsCounts = chartsMapper.getScheduleTerminalCount4Year(dto);
            map = getScheduleTerminalCountData(chartsCounts);
        } else if (ConstantsUtil.CountType.MONTH.name().equals(countType)) {
            List<ChartsDto> chartsCounts = chartsMapper.getScheduleTerminalCount4Month(dto);
            map = getScheduleTerminalCountData(chartsCounts);
        } else if (ConstantsUtil.CountType.DATE.name().equals(countType)) {
            List<ChartsDto> chartsCounts = chartsMapper.getScheduleTerminalCount4Date(dto);
            map = getScheduleTerminalCountData(chartsCounts);
        }
        return map;
    }

    private Map<String, Object> getScheduleTerminalCountData(List<ChartsDto> chartsCounts) {
        Map<String, Integer> map = new HashMap<String, Integer>();
        List<ScheduleTerminal> scheduleTerminals = chartsMapper.getScheduleTerminals();
        List<DictPatientSource> sources = dictPatientSourceService.getListAll();
        int total = 0;
        for (ChartsDto chartsDto : chartsCounts) {
            String key = chartsDto.getComputerName() + "_" + chartsDto.getPatientSource();
            map.put(key, chartsDto.getCount());
            total += ((chartsDto.getCount() != null) ? chartsDto.getCount() : 0);
        }
        Map<String, Object> result = new TreeMap<>();
        List<Map<String, Object>> list = new ArrayList<>();
        for (ScheduleTerminal terminal : scheduleTerminals) {
            Map<String, Object> m = new TreeMap<>();
            m.put("terminal", terminal.getComputerName());
            int sum = 0;
            for (DictPatientSource source : sources) {
                String key2 = terminal.getComputerName() + "_" + source.getPatientSourceName();
                Integer value = map.get(key2);
                sum += ((value != null) ? value : 0);
                m.put("source" + source.getPatientSourceCode(), (value != null) ? value : 0);
            }
            m.put("sum", sum);
            if (sum > 0) {
                m.put("ratio", BigDecimalUtil.divide(sum, total, 2));
            }
            list.add(m);
        }
        String columnStr = "[{\"prop\":\"terminal\",\"label\":\"预约终端\"},";
        columnStr = getColumnString(columnStr, sources);
        result.put("column", JSON.parse(columnStr));
        result.put("data", list);
        return result;
    }

    @Override
    public Map<String, Object> getReqDeptCount(ChartsDto dto) {
        String countType = dto.getCountType();
        DictDeptDto dd = new DictDeptDto();
        dd.setClinicAttr("0");
        dd.setHospitalCode(dto.getReqHospitalCode());
        dd.setExamClass(dto.getExamClass());
        List<DictDept> depts = dictDeptService.getPerformDept(dd);
        Map<String, Object> map = null;
        dto.setExamClasses(CommonUtil.split2List(dto.getExamClass()));
        if (ConstantsUtil.CountType.YEAR.name().equals(countType)) {
            List<ChartsDto> chartsCounts = chartsMapper.getReqDeptCount4Year(dto);
            map = getDeptCountData(depts, chartsCounts);
        } else if (ConstantsUtil.CountType.MONTH.name().equals(countType)) {
            List<ChartsDto> chartsCounts = chartsMapper.getReqDeptCount4Month(dto);
            map = getDeptCountData(depts, chartsCounts);
        } else if (ConstantsUtil.CountType.DATE.name().equals(countType)) {
            List<ChartsDto> chartsCounts = chartsMapper.getReqDeptCount4Date(dto);
            map = getDeptCountData(depts, chartsCounts);
        }
        return map;
    }

    private Map<String, Object> getDeptCountData(List<DictDept> depts, List<ChartsDto> chartsCounts) {
        Map<String, Integer> map = new HashMap<String, Integer>();
        List<DictPatientSource> sources = dictPatientSourceService.getListAll();
        int total = 0;
        for (ChartsDto chartsDto : chartsCounts) {
            String key = (chartsDto.getReqDeptCode() != null) ? chartsDto.getReqDeptCode() : (chartsDto.getPerformDeptCode() + "_" + chartsDto.getPatientSource());
            map.put(key, chartsDto.getCount());
            total += ((chartsDto.getCount() != null) ? chartsDto.getCount() : 0);
        }
        Map<String, Object> result = new TreeMap<String, Object>();
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        for (DictDept dept : depts) {
            Map<String, Object> m = new TreeMap<String, Object>();
            m.put("deptName", dept.getDeptName());
            int sum = 0;
            for (DictPatientSource source : sources) {
                String key2 = dept.getDeptCode() + "_" + source.getPatientSourceName();
                Integer value = map.get(key2);
                sum += ((value != null) ? value : 0);
                m.put("source" + source.getPatientSourceCode(), (value != null) ? value : 0);
            }
            m.put("sum", sum);
            if (sum > 0) {
                m.put("ratio", BigDecimalUtil.divide((double) sum, (double) total, 2));
            }
            list.add(m);
        }
        String columnStr = "[{\"prop\":\"deptName\",\"label\":\"科室名称\"},";
        columnStr = getColumnString(columnStr, sources);
        result.put("column", JSON.parse(columnStr));
        result.put("data", list);
        return result;
    }

    @Override
    public Map<String, Object> getPerformDeptCount(ChartsDto dto) {
        String countType = dto.getCountType();
        DictDeptDto dd = new DictDeptDto();
        dd.setClinicAttr("1");
        dd.setHospitalCode(dto.getReqHospitalCode());
        dd.setExamClass(dto.getExamClass());
        List<DictDept> depts = dictDeptService.getPerformDept(dd);
        Map<String, Object> map = null;
        dto.setExamClasses(CommonUtil.split2List(dto.getExamClass()));
        if (ConstantsUtil.CountType.YEAR.name().equals(countType)) {
            List<ChartsDto> chartsCounts = chartsMapper.getPerformDeptCount4Year(dto);
            map = getDeptCountData(depts, chartsCounts);
        } else if (ConstantsUtil.CountType.MONTH.name().equals(countType)) {
            List<ChartsDto> chartsCounts = chartsMapper.getPerformDeptCount4Month(dto);
            map = getDeptCountData(depts, chartsCounts);
        } else if (ConstantsUtil.CountType.DATE.name().equals(countType)) {
            List<ChartsDto> chartsCounts = chartsMapper.getPerformDeptCount4Date(dto);
            map = getDeptCountData(depts, chartsCounts);
        }
        return map;
    }

    @Override
    public Map<String, Object> getExamQueueCount(ChartsDto dto) {
        String countType = dto.getCountType();
        DictExamQueue dictExamQueue = new DictExamQueue();
        dictExamQueue.setExamClass(dto.getExamClass());
        dictExamQueue.setQueueType("0");
        List<DictExamQueue> queues = dictExamQueueService.getQueueNameList(dictExamQueue);
        Map<String, Object> map = null;
        dto.setExamClasses(CommonUtil.split2List(dto.getExamClass()));
        if (ConstantsUtil.CountType.YEAR.name().equals(countType)) {
            List<ChartsDto> chartsCounts = chartsMapper.getExamQueueCount4Year(dto);
            map = getScheduleQueueData(queues, chartsCounts);
        } else if (ConstantsUtil.CountType.MONTH.name().equals(countType)) {
            List<ChartsDto> chartsCounts = chartsMapper.getExamQueueCount4Month(dto);
            map = getScheduleQueueData(queues, chartsCounts);
        } else if (ConstantsUtil.CountType.DATE.name().equals(countType)) {
            List<ChartsDto> chartsCounts = chartsMapper.getExamQueueCount4Date(dto);
            map = getScheduleQueueData(queues, chartsCounts);
        }
        return map;
    }

    @Override
    public Map<String, Object> getUserScheduleCount(ChartsDto dto) {
        List<ChartsDto> chartsDtos = chartsMapper.getUserScheduleCount(dto);
        List<String> column = new ArrayList<>();
        Map<String, List<ChartsDto>> dataMap = new HashMap<>();
        Map<String, Integer> deptSum = new HashMap<>();
        Map<String, Object> resultMap = new HashMap<>();
        Map<String, Integer> sumMap = new HashMap<>();
        column.add("操作人");
        for (ChartsDto charts : chartsDtos) {
            if (!column.contains(charts.getPerformDeptName())) {
                column.add(charts.getPerformDeptName());
            }
            if (!dataMap.containsKey(charts.getUserName())) {
                List<ChartsDto> dataList = new ArrayList<>();
                ChartsDto data = new ChartsDto();
                data.setPerformDeptName(charts.getPerformDeptName());
                data.setCount(charts.getCount());
                data.setSum(charts.getCount());
                dataList.add(data);
                dataMap.put(charts.getUserName(), dataList);
                sumMap.put(charts.getUserName(), data.getSum());
            } else {
                List<ChartsDto> dataList = dataMap.get(charts.getUserName());
                ChartsDto data = new ChartsDto();
                data.setPerformDeptName(charts.getPerformDeptName());
                data.setCount(charts.getCount());
                for (ChartsDto chartsDto : dataList) {
                    data.setSum(chartsDto.getSum() + charts.getCount());
                }
                dataList.add(data);
                sumMap.put(charts.getUserName(), data.getSum());
            }
            if (!deptSum.containsKey(charts.getPerformDeptName())) {
                deptSum.put(charts.getPerformDeptName(), charts.getCount());
            } else {
                Integer deptCount = deptSum.get(charts.getPerformDeptName());
                deptSum.replace(charts.getPerformDeptName(), deptCount, deptCount + charts.getCount());
            }
        }
        for (String s : dataMap.keySet()) {
            List<ChartsDto> dataList = dataMap.get(s);
            ChartsDto data = new ChartsDto();
            data.setPerformDeptName("合计");
            data.setCount(sumMap.get(s));
            dataList.add(data);
        }
        column.add("合计");
        int total = 0;
        Set<String> set = deptSum.keySet();
        for (String key : set) {
            total += deptSum.get(key);
        }
        deptSum.put("合计", total);
        resultMap.put("column", column);
        resultMap.put("dataMap", dataMap);
        resultMap.put("deptSum", deptSum);
        return resultMap;
    }

    private Map<String, Object> getScheduleQueueData(List<DictExamQueue> queues, List<ChartsDto> chartsCounts) {
        Map<String, Integer> map = new HashMap<>();
        List<DictPatientSource> sources = dictPatientSourceService.getListAll();
        int total = 0;
        for (ChartsDto chartsDto : chartsCounts) {
            String key = chartsDto.getQueueName() + "_" + chartsDto.getPatientSource();
            map.put(key, chartsDto.getCount());
            total += ((chartsDto.getCount() != null) ? chartsDto.getCount() : 0);
        }
        Map<String, Object> result = new TreeMap<>();
        List<Map<String, Object>> list = new ArrayList<>();
        for (DictExamQueue queue : queues) {
            Map<String, Object> m = new TreeMap<>();
            m.put("queueName", queue.getQueueName());
            int sum = 0;
            for (DictPatientSource source : sources) {
                String key2 = queue.getQueueName() + "_" + source.getPatientSourceName();
                Integer value = map.get(key2);
                sum += ((value != null) ? value : 0);
                m.put("source" + source.getPatientSourceCode(), (value != null) ? value : 0);
            }
            m.put("sum", sum);
            if (sum > 0) {
                m.put("ratio", BigDecimalUtil.divide((double) sum, (double) total, 2));
            }
            list.add(m);
        }
        String columnStr = "[{\"prop\":\"queueName\",\"label\":\"队列名称\"},";
        columnStr = getColumnString(columnStr, sources);
        result.put("column", JSON.parse(columnStr));
        result.put("data", list);
        return result;
    }

    /***
     * 爽约统计报表
     * @param dto
     * @return
     */
    @Override
    public List<Map<String, Object>> getReqDeptBreakPromiseCount(BreakPromiseCountDto dto) {
        List<Map<String, Object>> list = new ArrayList<>();
        NumberFormat numberFormat = NumberFormat.getInstance();
        String countType = dto.getCountType();
        dto.setExamClasses(CommonUtil.split2List(dto.getExamClass()));
        numberFormat.setMaximumFractionDigits(2);
        String result = null;
        String outPatientBreakPromiseRate = null;
        String hospitalBreakPromiseRate = null;
        DictDeptDto dd = new DictDeptDto();
        dd.setHospitalCode(dto.getReqHospitalCode());
        dd.setDeptCode(dto.getReqDeptCode());
        dd.setClinicAttr("0");
        List<DictDept> dictDepts = dictDeptService.getList(dd);
        Map<String, Object> itemHashMap;
        List<BreakPromiseCountDto> breakPromiseCounts2;
        List<BreakPromiseCountDto> breakPromiseCounts;
        if (ConstantsUtil.CountType.YEAR.name().equals(countType)) {
            breakPromiseCounts = chartsMapper.getReqPatientSourceCount4Year(dto);
            breakPromiseCounts2 = iChartsService.getReqDeptBreakPromiseCount4Year(dto);
            Map<String, Integer> map_breakPromiseCounts = new HashMap<>();
            Map<String, Integer> map_breakPromiseCounts2 = new HashMap<>();

            for (BreakPromiseCountDto breakPromiseCount : breakPromiseCounts) {
                String key = breakPromiseCount.getReqDeptCode() + "_" + breakPromiseCount.getPatientSource() + "_" + breakPromiseCount.getScheduleYear();
                if (map_breakPromiseCounts.containsKey(key)) {
                    map_breakPromiseCounts.put(key, map_breakPromiseCounts.get(key) + breakPromiseCount.getCount());
                } else {
                    map_breakPromiseCounts.put(key, breakPromiseCount.getCount());
                }
            }
            for (BreakPromiseCountDto breakPromiseCount2 : breakPromiseCounts2) {
                String key = breakPromiseCount2.getReqDeptCode() + "_" + breakPromiseCount2.getPatientSource() + "_" + breakPromiseCount2.getScheduleYear();
                if (map_breakPromiseCounts2.containsKey(key)) {
                    map_breakPromiseCounts2.put(key, map_breakPromiseCounts2.get(key) + breakPromiseCount2.getCount());
                } else {
                    map_breakPromiseCounts2.put(key, breakPromiseCount2.getCount());
                }
            }
            String year = dto.getPerformStartDate().substring(0, dto.getPerformStartDate().indexOf("-"));
            for (DictDept dept : dictDepts) {
                itemHashMap = new HashMap<>();
                itemHashMap.put("reqDeptCode", dept.getDeptCode());
                itemHashMap.put("reqDeptName", dept.getDeptName());
                itemHashMap.put("year", year);
                String key2 = dept.getDeptCode() + "_门诊_" + year;
                int outPatientAppointmentNum = 0;
                if (map_breakPromiseCounts.containsKey(key2)) {
                    outPatientAppointmentNum = map_breakPromiseCounts.get(key2);
                    itemHashMap.put("outPatientAppointmentNum", map_breakPromiseCounts.get(key2));
                } else {
                    itemHashMap.put("outPatientAppointmentNum", 0);
                }
                int outPatientBreakPromiseNum = 0;
                if (map_breakPromiseCounts2.containsKey(key2)) {
                    outPatientBreakPromiseNum = map_breakPromiseCounts2.get(key2);
                    itemHashMap.put("outPatientBreakPromiseNum", map_breakPromiseCounts2.get(key2));
                } else {
                    itemHashMap.put("outPatientBreakPromiseNum", 0);
                }
                String key3 = dept.getDeptCode() + "_住院_" + year;
                int hospitalAppointmentNum = 0;
                if (map_breakPromiseCounts.containsKey(key3)) {
                    hospitalAppointmentNum = map_breakPromiseCounts.get(key3);
                    itemHashMap.put("hospitalAppointmentNum", map_breakPromiseCounts.get(key3));
                } else {
                    itemHashMap.put("hospitalAppointmentNum", 0);
                }
                int hospitalBreakPromiseNum = 0;
                if (map_breakPromiseCounts2.containsKey(key3)) {
                    hospitalBreakPromiseNum = map_breakPromiseCounts2.get(key3);
                    itemHashMap.put("hospitalBreakPromiseNum", map_breakPromiseCounts2.get(key3));
                } else {
                    itemHashMap.put("hospitalBreakPromiseNum", 0);
                }
                int appointmentTotal = outPatientAppointmentNum + hospitalAppointmentNum;
                itemHashMap.put("appointmentTotal", Math.max(appointmentTotal, 0));
                int breakPromiseTotal = outPatientBreakPromiseNum + hospitalBreakPromiseNum;
                itemHashMap.put("breakPromiseTotal", Math.max(breakPromiseTotal, 0));
                if (breakPromiseTotal > 0 && appointmentTotal > 0) {
                    result = numberFormat.format(breakPromiseTotal / (float) appointmentTotal * 100.0f);
                    itemHashMap.put("breakPromiseRate", result + "%");
                } else {
                    itemHashMap.put("breakPromiseRate", "0%");
                }
                itemHashMap.put("outPatientAppointmentNum", Math.max(outPatientAppointmentNum, 0));
                itemHashMap.put("outPatientBreakPromiseNum", Math.max(outPatientBreakPromiseNum, 0));
                if (outPatientBreakPromiseNum > 0 && outPatientAppointmentNum > 0) {
                    outPatientBreakPromiseRate = numberFormat.format(outPatientBreakPromiseNum / (float) outPatientAppointmentNum * 100.0f);
                    itemHashMap.put("outPatientBreakPromiseRate", outPatientBreakPromiseRate + "%");
                } else {
                    itemHashMap.put("outPatientBreakPromiseRate", "0%");
                }
                itemHashMap.put("hospitalAppointmentNum", Math.max(hospitalAppointmentNum, 0));
                itemHashMap.put("hospitalBreakPromiseNum", Math.max(hospitalBreakPromiseNum, 0));
                if (hospitalBreakPromiseNum > 0 && hospitalAppointmentNum > 0) {
                    hospitalBreakPromiseRate = numberFormat.format(hospitalBreakPromiseNum / (float) hospitalAppointmentNum * 100.0f);
                    itemHashMap.put("hospitalBreakPromiseRate", hospitalBreakPromiseRate + "%");
                } else {
                    itemHashMap.put("hospitalBreakPromiseRate", "0%");
                }
                list.add(itemHashMap);
            }
        } else if (ConstantsUtil.CountType.MONTH.name().equals(countType)) {
            breakPromiseCounts = chartsMapper.getReqPatientSourceCount4Month(dto);
            breakPromiseCounts2 = iChartsService.getReqDeptBreakPromiseCount4Month(dto);
            Map<String, Integer> map_breakPromiseCounts = new HashMap<>();
            Map<String, Integer> map_breakPromiseCounts2 = new HashMap<>();
            for (BreakPromiseCountDto breakPromiseCount : breakPromiseCounts) {
                String key = breakPromiseCount.getReqDeptCode() + "_" + breakPromiseCount.getPatientSource() + "_" + breakPromiseCount.getScheduleMonth();
                if (map_breakPromiseCounts.containsKey(key)) {
                    map_breakPromiseCounts.put(key, map_breakPromiseCounts.get(key) + breakPromiseCount.getCount());
                } else {
                    map_breakPromiseCounts.put(key, breakPromiseCount.getCount());
                }
            }
            for (BreakPromiseCountDto breakPromiseCount2 : breakPromiseCounts2) {
                String key = breakPromiseCount2.getReqDeptCode() + "_" + breakPromiseCount2.getPatientSource() + "_" + breakPromiseCount2.getScheduleMonth();
                if (map_breakPromiseCounts2.containsKey(key)) {
                    map_breakPromiseCounts2.put(key, map_breakPromiseCounts2.get(key) + breakPromiseCount2.getCount());
                } else {
                    map_breakPromiseCounts2.put(key, breakPromiseCount2.getCount());
                }
            }
            String month = dto.getPerformStartDate().substring(dto.getPerformStartDate().indexOf("-") + 1, dto.getPerformStartDate().lastIndexOf("-"));
            for (DictDept dept : dictDepts) {
                itemHashMap = new HashMap<>();
                itemHashMap.put("reqDeptCode", dept.getDeptCode());
                itemHashMap.put("reqDeptName", dept.getDeptName());
                itemHashMap.put("month", month);
                String key2 = dept.getDeptCode() + "_门诊_" + month;
                int outPatientAppointmentNum = 0;
                if (map_breakPromiseCounts.containsKey(key2)) {
                    outPatientAppointmentNum = map_breakPromiseCounts.get(key2);
                    itemHashMap.put("outPatientAppointmentNum", map_breakPromiseCounts.get(key2));
                } else {
                    itemHashMap.put("outPatientAppointmentNum", 0);
                }
                int outPatientBreakPromiseNum = 0;
                if (map_breakPromiseCounts2.containsKey(key2)) {
                    outPatientBreakPromiseNum = map_breakPromiseCounts2.get(key2);
                    itemHashMap.put("outPatientBreakPromiseNum", map_breakPromiseCounts2.get(key2));
                } else {
                    itemHashMap.put("outPatientBreakPromiseNum", 0);
                }
                String key3 = dept.getDeptCode() + "_住院_" + month;
                int hospitalAppointmentNum = 0;
                if (map_breakPromiseCounts.containsKey(key3)) {
                    hospitalAppointmentNum = map_breakPromiseCounts.get(key3);
                    itemHashMap.put("hospitalAppointmentNum", map_breakPromiseCounts.get(key3));
                } else {
                    itemHashMap.put("hospitalAppointmentNum", 0);
                }
                int hospitalBreakPromiseNum = 0;
                if (map_breakPromiseCounts2.containsKey(key3)) {
                    hospitalBreakPromiseNum = map_breakPromiseCounts2.get(key3);
                    itemHashMap.put("hospitalBreakPromiseNum", map_breakPromiseCounts2.get(key3));
                } else {
                    itemHashMap.put("hospitalBreakPromiseNum", 0);
                }
                int appointmentTotal = outPatientAppointmentNum + hospitalAppointmentNum;
                itemHashMap.put("appointmentTotal", Math.max(appointmentTotal, 0));
                int breakPromiseTotal = outPatientBreakPromiseNum + hospitalBreakPromiseNum;
                itemHashMap.put("breakPromiseTotal", Math.max(breakPromiseTotal, 0));
                if (breakPromiseTotal > 0 && appointmentTotal > 0) {
                    result = numberFormat.format(breakPromiseTotal / (float) appointmentTotal * 100.0f);
                    itemHashMap.put("breakPromiseRate", result + "%");
                } else {
                    itemHashMap.put("breakPromiseRate", "0%");
                }
                itemHashMap.put("outPatientAppointmentNum", Math.max(outPatientAppointmentNum, 0));
                itemHashMap.put("outPatientBreakPromiseNum", Math.max(outPatientBreakPromiseNum, 0));
                if (outPatientBreakPromiseNum > 0 && outPatientAppointmentNum > 0) {
                    outPatientBreakPromiseRate = numberFormat.format(outPatientBreakPromiseNum / (float) outPatientAppointmentNum * 100.0f);
                    itemHashMap.put("outPatientBreakPromiseRate", outPatientBreakPromiseRate + "%");
                } else {
                    itemHashMap.put("outPatientBreakPromiseRate", "0%");
                }
                itemHashMap.put("hospitalAppointmentNum", Math.max(hospitalAppointmentNum, 0));
                itemHashMap.put("hospitalBreakPromiseNum", Math.max(hospitalBreakPromiseNum, 0));
                if (hospitalBreakPromiseNum > 0 && hospitalAppointmentNum > 0) {
                    hospitalBreakPromiseRate = numberFormat.format(hospitalBreakPromiseNum / (float) hospitalAppointmentNum * 100.0f);
                    itemHashMap.put("hospitalBreakPromiseRate", hospitalBreakPromiseRate + "%");
                } else {
                    itemHashMap.put("hospitalBreakPromiseRate", "0%");
                }
                list.add(itemHashMap);
            }
        } else if (ConstantsUtil.CountType.DATE.name().equals(countType)) {
            breakPromiseCounts = chartsMapper.getReqPatientSourceCount4Date(dto);
            breakPromiseCounts2 = iChartsService.getReqDeptBreakPromiseCount4Date(dto);
            Map<String, Integer> map_breakPromiseCounts = new HashMap<>();
            Map<String, Integer> map_breakPromiseCounts2 = new HashMap<>();
            for (BreakPromiseCountDto breakPromiseCount : breakPromiseCounts) {
                String key = breakPromiseCount.getReqDeptCode() + "_" + breakPromiseCount.getPatientSource() + "_" + breakPromiseCount.getScheduledDay();
                if (map_breakPromiseCounts.containsKey(key)) {
                    map_breakPromiseCounts.put(key, map_breakPromiseCounts.get(key) + breakPromiseCount.getCount());
                } else {
                    map_breakPromiseCounts.put(key, breakPromiseCount.getCount());
                }
            }
            for (BreakPromiseCountDto breakPromiseCount2 : breakPromiseCounts2) {
                String key = breakPromiseCount2.getReqDeptCode() + "_" + breakPromiseCount2.getPatientSource() + "_" + breakPromiseCount2.getScheduledDay();
                if (map_breakPromiseCounts2.containsKey(key)) {
                    map_breakPromiseCounts2.put(key, map_breakPromiseCounts2.get(key) + breakPromiseCount2.getCount());
                } else {
                    map_breakPromiseCounts2.put(key, breakPromiseCount2.getCount());
                }
            }
            String day = dto.getPerformStartDate() + "~" + dto.getPerformEndDate();
            for (DictDept dept2 : dictDepts) {
                itemHashMap = new HashMap<>();
                itemHashMap.put("reqDeptCode", dept2.getDeptCode());
                itemHashMap.put("reqDeptName", dept2.getDeptName());
                itemHashMap.put("day", day);
                String key4 = dept2.getDeptCode() + "_门诊";
                int outPatientAppointmentNum2 = 0;
                if (map_breakPromiseCounts.containsKey(key4)) {
                    outPatientAppointmentNum2 = map_breakPromiseCounts.get(key4);
                    itemHashMap.put("outPatientAppointmentNum", map_breakPromiseCounts.get(key4));
                } else {
                    itemHashMap.put("outPatientAppointmentNum", 0);
                }
                int outPatientBreakPromiseNum2 = 0;
                if (map_breakPromiseCounts2.containsKey(key4)) {
                    outPatientBreakPromiseNum2 = map_breakPromiseCounts2.get(key4);
                    itemHashMap.put("outPatientBreakPromiseNum", map_breakPromiseCounts2.get(key4));
                } else {
                    itemHashMap.put("outPatientBreakPromiseNum", 0);
                }
                String key5 = dept2.getDeptCode() + "_住院";
                int hospitalAppointmentNum2 = 0;
                if (map_breakPromiseCounts.containsKey(key5)) {
                    hospitalAppointmentNum2 = map_breakPromiseCounts.get(key5);
                    itemHashMap.put("hospitalAppointmentNum", map_breakPromiseCounts.get(key5));
                } else {
                    itemHashMap.put("hospitalAppointmentNum", 0);
                }
                int hospitalBreakPromiseNum2 = 0;
                if (map_breakPromiseCounts2.containsKey(key5)) {
                    hospitalBreakPromiseNum2 = map_breakPromiseCounts2.get(key5);
                    itemHashMap.put("hospitalBreakPromiseNum", map_breakPromiseCounts2.get(key5));
                } else {
                    itemHashMap.put("hospitalBreakPromiseNum", 0);
                }
                int appointmentTotal2 = outPatientAppointmentNum2 + hospitalAppointmentNum2;
                itemHashMap.put("appointmentTotal", Math.max(appointmentTotal2, 0));
                int breakPromiseTotal2 = outPatientBreakPromiseNum2 + hospitalBreakPromiseNum2;
                itemHashMap.put("breakPromiseTotal", Math.max(breakPromiseTotal2, 0));
                if (breakPromiseTotal2 > 0 && appointmentTotal2 > 0) {
                    result = numberFormat.format(breakPromiseTotal2 / (float) appointmentTotal2 * 100.0f);
                    itemHashMap.put("breakPromiseRate", result + "%");
                } else {
                    itemHashMap.put("breakPromiseRate", "0%");
                }
                itemHashMap.put("outPatientAppointmentNum", Math.max(outPatientAppointmentNum2, 0));
                itemHashMap.put("outPatientBreakPromiseNum", Math.max(outPatientBreakPromiseNum2, 0));
                if (outPatientBreakPromiseNum2 > 0 && outPatientAppointmentNum2 > 0) {
                    outPatientBreakPromiseRate = numberFormat.format(outPatientBreakPromiseNum2 / (float) outPatientAppointmentNum2 * 100.0f);
                    itemHashMap.put("outPatientBreakPromiseRate", outPatientBreakPromiseRate + "%");
                } else {
                    itemHashMap.put("outPatientBreakPromiseRate", "0%");
                }
                itemHashMap.put("hospitalAppointmentNum", Math.max(hospitalAppointmentNum2, 0));
                itemHashMap.put("hospitalBreakPromiseNum", Math.max(hospitalBreakPromiseNum2, 0));
                if (hospitalBreakPromiseNum2 > 0 && hospitalAppointmentNum2 > 0) {
                    hospitalBreakPromiseRate = numberFormat.format(hospitalBreakPromiseNum2 / (float) hospitalAppointmentNum2 * 100.0f);
                    itemHashMap.put("hospitalBreakPromiseRate", hospitalBreakPromiseRate + "%");
                } else {
                    itemHashMap.put("hospitalBreakPromiseRate", "0%");
                }
                list.add(itemHashMap);
            }
        }
        return list;
    }

    private String getColumnString(String s, List<DictPatientSource> list) {
        for (DictPatientSource source : list) {
            s = s + "{\"prop\":\"source" + source.getPatientSourceCode() + "\",\"label\":\"" + source.getPatientSourceName() + "\"},";
        }
        s += "{\"prop\":\"sum\",\"label\":\"合计\"},{\"prop\":\"ratio\",\"label\":\"占比\"}]";
        return s;
    }

    @Override
    public List<BreakPromiseCountDto> getReqDeptBreakPromiseCount4Year(BreakPromiseCountDto param) {
        List<BreakPromiseCountDto> bpcYear1 = chartsMapper.getReqDeptBreakPromiseCount4Year1(param);
        List<BreakPromiseCountDto> bpcYear2 = chartsMapper.getReqDeptBreakPromiseCount4Year2(param);
        List<BreakPromiseCountDto> bpcYear3 = chartsMapper.getReqDeptBreakPromiseCount4Year3(param);
        List<BreakPromiseCountDto> bpcYear4 = new ArrayList<BreakPromiseCountDto>();
        for (BreakPromiseCountDto bpc1 : bpcYear1) {
            if (!bpcYear4.contains(bpc1)) {
                bpcYear4.add(bpc1);
            }
        }
        for (BreakPromiseCountDto bpc2 : bpcYear2) {
            if (!bpcYear4.contains(bpc2)) {
                bpcYear4.add(bpc2);
            }
        }
        for (BreakPromiseCountDto bpc3 : bpcYear3) {
            if (!bpcYear4.contains(bpc3)) {
                bpcYear4.add(bpc3);
            }
        }
        return bpcYear4;
    }

    @Override
    public List<BreakPromiseCountDto> getReqDeptBreakPromiseCount4Month(BreakPromiseCountDto param) {
        List<BreakPromiseCountDto> bpcMonth1 = chartsMapper.getReqDeptBreakPromiseCount4Month1(param);
        List<BreakPromiseCountDto> bpcMonth2 = chartsMapper.getReqDeptBreakPromiseCount4Month2(param);
        List<BreakPromiseCountDto> bpcMonth3 = chartsMapper.getReqDeptBreakPromiseCount4Month3(param);
        List<BreakPromiseCountDto> bpcMonth4 = new ArrayList<BreakPromiseCountDto>();
        for (BreakPromiseCountDto bpc1 : bpcMonth1) {
            if (!bpcMonth4.contains(bpc1)) {
                bpcMonth4.add(bpc1);
            }
        }
        for (BreakPromiseCountDto bpc2 : bpcMonth2) {
            if (!bpcMonth4.contains(bpc2)) {
                bpcMonth4.add(bpc2);
            }
        }
        for (BreakPromiseCountDto bpc3 : bpcMonth3) {
            if (!bpcMonth4.contains(bpc3)) {
                bpcMonth4.add(bpc3);
            }
        }
        return bpcMonth4;
    }

    @Override
    public List<BreakPromiseCountDto> getReqDeptBreakPromiseCount4Date(BreakPromiseCountDto param) {
        List<BreakPromiseCountDto> bpcDate1 = chartsMapper.getReqDeptBreakPromiseCount4Date1(param);
        List<BreakPromiseCountDto> bpcDate2 = chartsMapper.getReqDeptBreakPromiseCount4Date2(param);
        List<BreakPromiseCountDto> bpcDate3 = chartsMapper.getReqDeptBreakPromiseCount4Date3(param);
        List<BreakPromiseCountDto> bpcDate4 = new ArrayList<BreakPromiseCountDto>();
        for (BreakPromiseCountDto bpc1 : bpcDate1) {
            if (!bpcDate4.contains(bpc1)) {
                bpcDate4.add(bpc1);
            }
        }
        for (BreakPromiseCountDto bpc2 : bpcDate2) {
            if (!bpcDate4.contains(bpc2)) {
                bpcDate4.add(bpc2);
            }
        }
        for (BreakPromiseCountDto bpc3 : bpcDate3) {
            if (!bpcDate4.contains(bpc3)) {
                bpcDate4.add(bpc3);
            }
        }
        return bpcDate4;
    }

    @Override
    public List<ChartsDto> scheduleWordloadCount(ChartsDto dto) {
        String workLoadType = dto.getChooseWorkLoadType();
        List<String> names = new ArrayList<String>();
        if ("2".equals(workLoadType)) {
            DictDeptDto dd = new DictDeptDto();
            dd.setClinicAttr("0");
            dd.setHospitalCode(dto.getReqHospitalCode());
            dd.setExamClass(dto.getExamClass());
            List<DictDept> depts = dictDeptService.getPerformDept(dd);

            if (CollectionUtils.isNotEmpty(depts)) {
                names.addAll(depts.stream().map(DictDept::getDeptCode).collect(Collectors.toList()));
            }
            dto.setReqDepts(names);
        } else if ("3".equals(workLoadType)) {
            DictDeptDto dd = new DictDeptDto();
            dd.setClinicAttr("1");
            dd.setHospitalCode(dto.getReqHospitalCode());
            dd.setExamClass(dto.getExamClass());
            List<DictDept> depts = dictDeptService.getPerformDept(dd);
            if (CollectionUtils.isNotEmpty(depts)) {
                names.addAll(depts.stream().map(DictDept::getDeptCode).collect(Collectors.toList()));
            }
            dto.setPerformDepts(names);
        } else if ("5".equals(workLoadType)) {
            DictExamQueue dictExamQueue = new DictExamQueue();
            dictExamQueue.setExamClass(dto.getExamClass());
            dictExamQueue.setQueueType("0");
            List<DictExamQueue> queues = dictExamQueueService.getQueueNameList(dictExamQueue);
            if (CollectionUtils.isNotEmpty(queues)) {
                names.addAll(queues.stream().map(DictExamQueue::getQueueName).collect(Collectors.toList()));
            }
            dto.setScheduleQueueNames(names);
        }
        dto.setExamClasses(CommonUtil.split2List(dto.getExamClass()));
        List<ChartsDto> chartsDtos = chartsMapper.getWorkload(dto);
        int total = 0;
        int scheduleSum = 0;
        int updateSum = 0;
        int cancelSum = 0;
        ChartsDto chartsSum = new ChartsDto();
        for (ChartsDto chartsDto : chartsDtos) {
            int sum = chartsDto.getScheduleCount() + chartsDto.getUpdateCount() + chartsDto.getCancelCount();
            chartsDto.setSum(sum);
            total += sum;
            scheduleSum += chartsDto.getScheduleCount();
            updateSum += chartsDto.getUpdateCount();
            cancelSum += chartsDto.getCancelCount();
        }
        chartsSum.setScheduleSum(scheduleSum);
        chartsSum.setUpdateSum(updateSum);
        chartsSum.setCancelSum(cancelSum);
        chartsSum.setSum(scheduleSum + updateSum + cancelSum);
        for (ChartsDto chartsDto : chartsDtos) {
            chartsDto.setRatio(BigDecimalUtil.divide(chartsDto.getSum(), total, 2));
        }
        chartsDtos.add(chartsSum);
        return chartsDtos;
    }

    @Override
    public Map<String, Object> getScheduleOrgansCount(ChartsDto dto) {
        ChartsDto charts = new ChartsDto();
        charts.setStartDate(dto.getStartDate());
        charts.setEndDate(dto.getEndDate());
        String dateFormat = ConstantsUtil.DateFormat.getValue(dto.getCountType());
        charts.setDateFormat("'" + dateFormat + "'");
        charts.setExamClasses(CommonUtil.split2List(dto.getExamClass()));
        charts.setPerformDepts(CommonUtil.split2List(dto.getPerformDeptName()));
        charts.setQueueNameList(CommonUtil.split2List(dto.getQueueName()));
        charts.setCountType(dto.getCountType());
        List<ExamApplyDto> organsList = chartsMapper.getScheduleOrgans(charts);
        Map<String, List<DictExamQueueDto>> queuesMap = new HashMap<>();
        List<DictExamQueueDto> queue = new ArrayList<>();
        for (ExamApplyDto ea : organsList) {
            DictExamQueueDto deq = new DictExamQueueDto();
            deq.setQueueName(ea.getQueueName());
            queue.add(deq);
            if (queuesMap.containsKey(ea.getScheduledDate())) {
                List<DictExamQueueDto> queuesList = queuesMap.get(ea.getScheduledDate());
                queuesList.add(deq);
            } else {
                List<DictExamQueueDto> q = new ArrayList<>();
                q.add(deq);
                queuesMap.put(ea.getScheduledDate(), q);
            }
        }
        List<String> column = new ArrayList<>();
        int calendar = 1;
        if (ConstantsUtil.DateFormat.DATE.getKey().equals(dto.getCountType())) {
            calendar = 5;
            column = DateUtil.findDaysStr(dto.getStartDate(), dto.getEndDate());
        } else if (ConstantsUtil.DateFormat.MONTH.getKey().equals(dto.getCountType())) {
            calendar = 2;
            try {
                column = DateUtil.findMonthsStr(dto.getStartDate(), dto.getEndDate());
            } catch (ParseException ignored) {
            }
        } else {
            column = DateUtil.findYearsStr(dto.getStartDate(), dto.getEndDate());
        }
        Map<String, Object> maxLimitMap = getScheduleApmCount(dto, queue, queuesMap);
        Map<String, Object> resultMap = new LinkedHashMap<>();
        Map<String, Object> dateMap = new HashMap<>();
        Map<String, Object> queueNameMap = new HashMap<>();
        Map<String, Object> dateSize = new HashMap<>();
        Map<String, List<ExamApplyDto>> queueMap = new LinkedHashMap<>();
        for (ExamApplyDto applyDto : organsList) {
            String mapKey = applyDto.getScheduledDate() + applyDto.getQueueName();
            if (maxLimitMap.get(mapKey) == null) {
                continue;
            }
            double maxLimit = Double.parseDouble(maxLimitMap.get(mapKey) + "");
            double organsAvg = BigDecimalUtil.divide(applyDto.getOrgans(), maxLimit);
            if (queueMap.containsKey(applyDto.getQueueName())) {
                List<ExamApplyDto> dataList = queueMap.get(applyDto.getQueueName());
                ExamApplyDto data = new ExamApplyDto();
                data.setScheduledDate(applyDto.getScheduledDate());
                data.setQueueName(applyDto.getQueueName());
                data.setOrgans(BigDecimalUtil.round(organsAvg * 100.0, 2));
                dataList.add(data);
            } else {
                List<ExamApplyDto> dataList = new ArrayList<ExamApplyDto>();
                ExamApplyDto data = new ExamApplyDto();
                data.setScheduledDate(applyDto.getScheduledDate());
                data.setQueueName(applyDto.getQueueName());
                data.setOrgans(BigDecimalUtil.round(organsAvg * 100.0, 2));
                dataList.add(data);
                queueMap.put(applyDto.getQueueName(), dataList);
            }
            if (dateMap.size() > 0) {
                double dateOrgans = (dateMap.get(applyDto.getScheduledDate()) == null) ? 0.0 : Double.parseDouble(dateMap.get(applyDto.getScheduledDate()) + "");
                dateMap.put(applyDto.getScheduledDate(), BigDecimalUtil.add(dateOrgans, organsAvg));
            } else {
                dateMap.put(applyDto.getScheduledDate(), organsAvg);
            }
            double dateCount = (dateSize.get(applyDto.getScheduledDate()) == null) ? 0.0 : Double.parseDouble(dateSize.get(applyDto.getScheduledDate()) + "");
            dateSize.put(applyDto.getScheduledDate(), dateCount + 1.0);
            if (queueNameMap.size() > 0) {
                double queueNameOrgans = (queueNameMap.get(applyDto.getQueueName()) == null) ? 0.0 : Double.parseDouble(queueNameMap.get(applyDto.getQueueName()) + "");
                queueNameMap.put(applyDto.getQueueName(), BigDecimalUtil.add(queueNameOrgans, organsAvg));
            } else {
                queueNameMap.put(applyDto.getQueueName(), organsAvg);
            }
        }
        List<ExamApplyDto> data2 = new ArrayList<>();
        for (String key : queueMap.keySet()) {
            ExamApplyDto examApplyDto = new ExamApplyDto();
            examApplyDto.setQueueName(key);
            List<ExamApplyDto> dataList2 = queueMap.get(key);
            examApplyDto.setNumRate(dataList2);
            double queueAvg = BigDecimalUtil.divide(Double.parseDouble(queueNameMap.get(key) + ""), dataList2.size()) * 100.0;
            examApplyDto.setQueueAvg(String.valueOf(BigDecimalUtil.round(queueAvg, 2)));
            data2.add(examApplyDto);
        }
        Map<String, Object> dateAvg = new HashMap<>();
        for (String date : dateMap.keySet()) {
            double datAvg = BigDecimalUtil.divide(Double.parseDouble(dateMap.get(date) + ""), Double.parseDouble(dateSize.get(date) + "")) * 100.0;
            dateAvg.put(date, String.valueOf(BigDecimalUtil.round(datAvg, 2)));
        }
        resultMap.put("column", column);
        resultMap.put("data", data2);
        resultMap.put("dateAvg", dateAvg);
        return resultMap;
    }

    public Map<String, Object> getScheduleApmCount(ChartsDto dto, List<DictExamQueueDto> queues, Map<String, List<DictExamQueueDto>> queuesMap) {
        Map<String, Object> queueMap = new HashMap<String, Object>();
        String startDateStr = dto.getStartDate();
        String endDateStr = dto.getEndDate();
        if (ConstantsUtil.DateFormat.YEAR.getKey().equals(dto.getCountType())) {
            startDateStr += "-01-01";
            endDateStr += "-12-31";

        } else if (ConstantsUtil.DateFormat.MONTH.getKey().equals(dto.getCountType())) {
            startDateStr += "-01";
            endDateStr += "-31";
        }
        Date startDate = DateUtil.parse(startDateStr, DateUtil.FORMAT_DATE);
        Date endDate = DateUtil.parse(endDateStr, DateUtil.FORMAT_DATE);
        String dateFormat = ConstantsUtil.DateFormat.getValue(dto.getCountType());
        DictScheduleApmDto dsaComm = new DictScheduleApmDto();
        dsaComm.setQueues(queues);
        List<DictScheduleApmDto> lsApm3 = dictScheduleApmMapper.getCommonScheduleApm(dsaComm);
        while (startDate.compareTo(endDate) <= 0) {
            String dateForMat = DateUtil.date2Str(startDate, dateFormat);
            if (queuesMap.containsKey(dateForMat)) {
                List<DictExamQueueDto> queueList = queuesMap.get(dateForMat);
                Map<String, Object> apmMap = new HashMap<>();
                DictScheduleApmDto dictScheduleApmDto = new DictScheduleApmDto();
                dictScheduleApmDto.setScheduleDate(startDateStr);
                dictScheduleApmDto.setWeekDate(DateUtil.getWeek(startDateStr));
                dictScheduleApmDto.setQueues(queueList);
                List<DictScheduleApmDto> lsApm4 = dictScheduleApmMapper.getDateScheduleApm(dictScheduleApmDto);
                for (DictScheduleApmDto dsa : lsApm4) {
                    String key = dsa.getQueueName() + dsa.getTimeStart() + dsa.getDateStart() + dsa.getDateEnd();
                    if (!"1".equals(dsa.getStopFlag()) && !"2".equals(dsa.getStopFlag())) {
                        String queueKey = dateForMat + dsa.getQueueName();
                        double maxLimit = (queueMap.get(queueKey) == null) ? 0.0 : Double.parseDouble(queueMap.get(queueKey) + "");
                        queueMap.put(queueKey, BigDecimalUtil.add(maxLimit, (double) dsa.getMaxLimit()));
                        apmMap.put(key, 1);
                    }
                }
                List<DictScheduleApmDto> lsApm5 = dictScheduleApmMapper.getWeekScheduleApm(dictScheduleApmDto);
                for (DictScheduleApmDto dsa2 : lsApm5) {
                    String key2 = dsa2.getQueueName() + dsa2.getTimeStart() + dsa2.getDateStart() + dsa2.getDateEnd();
                    if (!apmMap.containsKey(key2) && !"1".equals(dsa2.getStopFlag()) && !"2".equals(dsa2.getStopFlag())) {
                        String queueKey2 = dateForMat + dsa2.getQueueName();
                        double maxLimit2 = (queueMap.get(queueKey2) == null) ? 0.0 : Double.parseDouble(queueMap.get(queueKey2) + "");
                        queueMap.put(queueKey2, BigDecimalUtil.add(maxLimit2, dsa2.getMaxLimit()));
                        apmMap.put(key2, 1);
                    }
                }
                for (DictScheduleApmDto dsa2 : lsApm3) {
                    String key2 = dsa2.getQueueName() + dsa2.getTimeStart() + dsa2.getDateStart() + dsa2.getDateEnd();
                    if (!apmMap.containsKey(key2) && !"1".equals(dsa2.getStopFlag()) && !"2".equals(dsa2.getStopFlag())) {
                        String queueKey2 = dateForMat + dsa2.getQueueName();
                        double maxLimit2 = (queueMap.get(queueKey2) == null) ? 0.0 : Double.parseDouble(queueMap.get(queueKey2) + "");
                        queueMap.put(queueKey2, BigDecimalUtil.add(maxLimit2, dsa2.getMaxLimit()));
                        apmMap.put(key2, 1);
                    }
                }
                if (ConstantsUtil.DateFormat.YEAR.getKey().equals(dto.getCountType())) {
                    startDateStr = DateUtil.date2Str(DateUtil.yearAdd(startDateStr, 1), DateUtil.FORMAT_DATE);
                }
                if (ConstantsUtil.DateFormat.MONTH.getKey().equals(dto.getCountType())) {
                    startDateStr = DateUtil.date2Str(DateUtil.mouthAdd(startDateStr, 1), DateUtil.FORMAT_DATE);
                } else {
                    startDateStr = DateUtil.date2Str(DateUtil.dateAdd(startDateStr, 1), DateUtil.FORMAT_DATE);
                }
                startDate = DateUtil.parse(startDateStr,DateUtil.FORMAT_DATE);
            } else {
                if (ConstantsUtil.DateFormat.YEAR.getKey().equals(dto.getCountType())) {
                    startDateStr = DateUtil.date2Str(DateUtil.yearAdd(startDateStr, 1), DateUtil.FORMAT_DATE);
                }
                if (ConstantsUtil.DateFormat.MONTH.getKey().equals(dto.getCountType())) {
                    startDateStr = DateUtil.date2Str(DateUtil.mouthAdd(startDateStr, 1), DateUtil.FORMAT_DATE);
                } else {
                    startDateStr = DateUtil.date2Str(DateUtil.dateAdd(startDateStr, 1), DateUtil.FORMAT_DATE);
                }
                startDate = DateUtil.parse(startDateStr,DateUtil.FORMAT_DATE);
            }
        }
        return queueMap;
    }

    @Override
    public Map<String, Object> getSignInCount(ChartsDto dto) {
        ChartsDto charts = new ChartsDto();
        charts.setStartDate(dto.getStartDate());
        charts.setEndDate(dto.getEndDate());
        charts.setExamClasses(CommonUtil.split2List(dto.getExamClass()));
        charts.setPerformDepts(CommonUtil.split2List(dto.getPerformDeptName()));
        charts.setQueueNameList(CommonUtil.split2List(dto.getQueueName()));
        List<ExamApplyDto> list = chartsMapper.getSignInCount(charts);
        Map<String, List<ExamApplyDto>> queueMap = new LinkedHashMap<String, List<ExamApplyDto>>();
        for (ExamApplyDto examApplyDto : list) {
            if (queueMap.containsKey(examApplyDto.getQueueName())) {
                List<ExamApplyDto> dataList = queueMap.get(examApplyDto.getQueueName());
                ExamApplyDto data = new ExamApplyDto();
                data.setScheduledDate(examApplyDto.getScheduledDate());
                data.setQueueName(examApplyDto.getQueueName());
                data.setPercent(BigDecimalUtil.divide(examApplyDto.getSignAmount(), examApplyDto.getAmount(), 4) * 100.0);
                dataList.add(data);
            } else {
                List<ExamApplyDto> dataList = new ArrayList<ExamApplyDto>();
                ExamApplyDto data = new ExamApplyDto();
                data.setScheduledDate(examApplyDto.getScheduledDate());
                data.setQueueName(examApplyDto.getQueueName());
                data.setPercent(BigDecimalUtil.divide(examApplyDto.getSignAmount(), examApplyDto.getAmount(), 4) * 100.0);
                dataList.add(data);
                queueMap.put(examApplyDto.getQueueName(), dataList);
            }
        }
        List<ExamApplyDto> data2 = new ArrayList<ExamApplyDto>();
        for (String key : queueMap.keySet()) {
            ExamApplyDto examApplyDto2 = new ExamApplyDto();
            examApplyDto2.setQueueName(key);
            List<ExamApplyDto> dataList2 = queueMap.get(key);
            double count = 0.0;
            for (ExamApplyDto applyDto : dataList2) {
                count += applyDto.getPercent();
            }
            examApplyDto2.setNumRate(dataList2);
            examApplyDto2.setQueueAvg(BigDecimalUtil.divide(count, dataList2.size(), 2) + "");
            data2.add(examApplyDto2);
        }
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put("data", data2);
        return resultMap;
    }

    @Override
    public Map<String, Object> getReqPhysicianCount(ChartsDto dto) {
        Map<String, Integer> map = new HashMap<String, Integer>();
        dto.setExamClasses(CommonUtil.split2List(dto.getExamClass()));
        List<ChartsDto> list = chartsMapper.getReqPhysicianCount(dto);
        List<DictPatientSource> sources = dictPatientSourceService.getListAll();
        List<String> reqPhysicianList = new ArrayList<String>();
        int total = 0;
        if (list != null && list.size() > 0) {
            for (ChartsDto chartsDto : list) {
                if (!reqPhysicianList.contains(chartsDto.getReqPhysician())) {
                    reqPhysicianList.add(chartsDto.getReqPhysician());
                }
                String key = chartsDto.getReqPhysician() + "_" + chartsDto.getPatientSource();
                map.put(key, chartsDto.getCount());
                total += ((chartsDto.getCount() != null) ? chartsDto.getCount() : 0);
            }
        }
        Map<String, Object> result = new TreeMap<String, Object>();
        List<Map<String, Object>> lis = new ArrayList<Map<String, Object>>();
        for (String reqPhysician : reqPhysicianList) {
            Map<String, Object> m = new TreeMap<String, Object>();
            m.put("reqPhysician", reqPhysician);
            int sum = 0;
            for (DictPatientSource source : sources) {
                String key2 = reqPhysician + "_" + source.getPatientSourceName();
                Integer value = map.get(key2);
                sum += ((value != null) ? value : 0);
                m.put("source" + source.getPatientSourceCode(), (value != null) ? value : 0);
            }
            m.put("sum", sum);
            if (sum > 0) {
                m.put("ratio", BigDecimalUtil.divide(sum, total, 2));
            }
            lis.add(m);
        }
        String columnStr = "[{\"prop\":\"reqPhysician\",\"label\":\"医生姓名\"},";
        columnStr = getColumnString(columnStr, sources);
        result.put("column", JSON.parse(columnStr));
        result.put("data", lis);
        return result;
    }

    @Override
    public List<Map<String, Object>> getScheduleCount(ChartsDto dto) {
        dto.setExamClasses(CommonUtil.split2List(dto.getExamClass()));
        List<Map<String, Object>> list = chartsMapper.getScheduleCount(dto);
        return list;
    }
}
